﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace ProjectEulerIssues
{
	public partial class Program
	{
		[SolutionInfo(Links = "http://wiki.san-ss.com.ar/project-euler-problem-106")]
		public static dynamic Problem106()
		{
			const int N = 12;

			int needCheckCount = 0;
			int vCount = 0;

			Action<List<int>, List<int>> needCheckDetect = (List<int> v1, List<int> v2) =>
			{
				if (v1.Count != v2.Count)
				{
					return;
				}
				for (int i = 0; i < v1.Count; i++)
				{
					if (v1[i] > v2[i])
					{
						needCheckCount++;
						return;
					}
				}
			};

			var vHash = new HashSet<string>();
			
			Action<List<int>, List<int>, List<int>> gen = null;
			gen = (List<int> v1, List<int> v2, List<int> v) => 
			{
				if (v1.Count != 0 && v2.Count != 0)
				{
					var key1 = string.Join(",", v1) + "-" + string.Join(",", v2);
					var key2 = string.Join(",", v2) + "-" + string.Join(",", v1);
					if (!vHash.Contains(key1) && !vHash.Contains(key2))
					{
						vHash.Add(key1);
						vHash.Add(key2);
						vCount++;
						needCheckDetect(v1, v2);
					}					
				}
				var maxV1 = v1.Count == 0 ? 0 : v1.Max();
				var maxV2 = v2.Count == 0 ? 0 : v2.Max();
				foreach (var vNum in v.ToList())
				{
					if (vNum > maxV1)
					{
						v1.Add(vNum);
						v.Remove(vNum);
						gen(v1, v2, v);
						v1.Remove(vNum);
						v.Add(vNum);
					}
					if (vNum > maxV2)
					{
						v2.Add(vNum);
						v.Remove(vNum);
						gen(v1, v2, v);						
						v2.Remove(vNum);
						v.Add(vNum);
					}
				}
			};

			Func<long> solve = () => 
			{
				var v1 = new List<int>();
				var v2 = new List<int>();
				var v = new List<int>(Enumerable.Range(1, N));
				gen(v1, v2, v);
				return needCheckCount;
			};
			return solve();
		}
	}
}
